
hypercube n confPStart 
   | (compMove sl nButtons iconfig) =:= desiredConfig = perm sl
   where 
      iconfig= initConf nButtons confPStart
      desiredConfig = replicate nButtons 0
      sl= sublist [1..nButtons]
      nButtons= pow 2 n
         
desiredConf m = replicate m 0
addConf conf1 conf2 = map modTwo (zipWith (+) conf1 conf2)
setButton n idx = st idx (desiredConf n)
modTwo = flip mod 2
initConf n = foldr (addConf . setButton n) (desiredConf n)
      
sublist []=[]
sublist (x:xs) = x: (sublist xs)
sublist (_:xs) = sublist xs 
    
perm []=[]
perm (x:xs)=y:perm ys
	where 
		(y,ys)= delete (x:xs)
		     
delete (x:xs) = (x,xs)
delete (x:xs) = (y,x:ys)
   where
      (y,ys) = delete xs

compMove [] _ ls=ls
compMove (x:xs) n ls= compMove xs n (zipWith f ls (move x n))
   where 
         f a b = mod (a + b) 2
         
move _ 0 = [1]
move a n
   | a == 2 && n == 1 = [1,1]
   | a <= m && n > 0 = move a (n-1) ++ set a m
   | a > m && n >0 = set (a -m) m ++ move (a -m) (n-1)
  where
    m = pow 2 (n-1)

set a n = st a (replicate n 0)
st a (x:xs)
  | a == 1 = 1:xs
  | otherwise = x:st (a-1) xs

pow a b = pw a b 1
pw a b acc
 | b > 0 = pw a (b-1) (a * acc)
 | b <= 0 =  acc
 
